package BitCreekLib; /**
 * @author Ivan Litsvinenka & Emanuele Ricci
 * Classe che rappresenta i MetaDati relativi a un torrent e salvati nell'HashTable del Tracker
 *
 */

import BitCreekTracker.TrackerPeer;

import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class TorrentMetaDati implements ITorrentMetaDati {
	public final Lock lock = new ReentrantLock();
    /**
     * MetaInfo relative al torrent
     */
    private MetaInfo torrent;

    /**
     * Le porte TCP e UDP utilizzate dal Tracker per questo torrent
     */
    private Ports trackerPorts;

    /**
     * Lista dei peers attualmente connessi al torrent
     */
    private ArrayList<TrackerPeer> peers;

    /**
     * Interfaccia del peer che ha pubblicato il torrent, utilizzata per effettuare la callback
     */
    private IRMIPeer iFirstSeeder;

    /**
     * Costruttore di TorrentMetaDati
     *
     * @param firstSeeder  Le informazioni sul peer che ha pubblicato il torrent
     * @param iFirstSeeder Interfaccia del primo seeder
     * @param t            MetaInfo sul torrent
     * @param ports Le porte TCP e UDP su cui i Peer si connetteranno al Tracker
     */
    public TorrentMetaDati ( Host firstSeeder, IRMIPeer iFirstSeeder, MetaInfo t, Ports ports) {
        this.peers = new ArrayList<TrackerPeer> ();
        this.peers.add ( new TrackerPeer(firstSeeder) );
        this.trackerPorts = ports;
        this.torrent = t;
        this.iFirstSeeder = iFirstSeeder;
    }

    public synchronized IRMIPeer getIFirstSeeder () {
        return iFirstSeeder;
    }

    public synchronized void setIFirstSeeder ( IRMIPeer firstSeeder ) {
        iFirstSeeder = firstSeeder;
    }

    public synchronized Ports getTrackerPorts () {
        return trackerPorts;
    }

    public synchronized void setTrackerPorts ( Ports ports ) {
        this.trackerPorts = ports;
    }

    public synchronized void addPeer ( Host peer ) {
    	
        for ( TrackerPeer tp : peers ) {
            if ( tp.getHost().getAddress().equals (peer.getAddress ()) ) {
                return;
            }
        }
        this.peers.add ( new TrackerPeer(peer) );
    }

    public synchronized void removePeer( TrackerPeer peer ) {
        for ( TrackerPeer tp : peers ) {
            if ( tp.getHost().getAddress().equals (peer.getHost().getAddress()) ) {
                this.peers.remove(tp);
                return;
            }
        }
    }

    public synchronized MetaInfo getMetaInfo () {
        return torrent;
    }

    public synchronized void setMetaInfo ( MetaInfo torrent ) {
        this.torrent = torrent;
    }

    public synchronized ArrayList<TrackerPeer> getPeers () {
        return this.peers;
    }

    public synchronized ArrayList<Host> getPeersList () {
        ArrayList<Host> t = new ArrayList<Host>();
        for ( TrackerPeer tp : this.peers )
            t.add(tp.getHost());

        return t;
    }

    public synchronized void setPeers ( ArrayList<TrackerPeer> peers ) {
        this.peers = peers;
    }

    public String toString () {
        return this.trackerPorts.toString()+" "+this.torrent.toString();
	}

}
